package indi.jp.project.business.jingying.service.impl;

import indi.jp.project.business.jingying.dao.BidsDAO;
import indi.jp.project.business.jingying.pojo.dto.BidsDTO;
import indi.jp.project.business.jingying.pojo.dto.BidsResultDTO;
import indi.jp.project.business.jingying.pojo.po.BidsPO;
import indi.jp.project.business.jingying.pojo.po.BidsSubPO;
import indi.jp.project.business.jingying.pojo.query.BidsQuery;
import indi.jp.project.business.jingying.pojo.vo.BidsSubVO;
import indi.jp.project.business.jingying.pojo.vo.BidsVO;
import indi.jp.project.business.jingying.service.BidsService;
import indi.jp.project.business.pub.pojo.ProjectStatusEnum;
import indi.jp.project.business.pub.pojo.po.ProjectPO;
import indi.jp.project.business.pub.service.ProjectService;
import indi.jp.project.core.entity.Datagrid;
import indi.jp.project.core.entity.JsonResult;
import indi.jp.project.core.entity.po.AttachmentPO;
import indi.jp.project.core.service.AttachmentService;
import indi.jp.project.core.util.SerialUtil;
import indi.jp.project.process.entity.*;
import indi.jp.project.process.service.FlowTaskService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.List;

/**
 * 投标实现
 *
 * @author jiangping
 * @date 2022/5/13
 */
@Service("bidsService")
public class BidsServiceImpl implements BidsService {

    @Resource
    private BidsDAO bidsDAO;

    @Resource
    private SerialUtil serialUtil;

    @Resource
    private AttachmentService attachmentService;

    @Resource
    private FlowTaskService flowTaskService;

    @Resource
    private ProjectService projectService;

    @Override
    public JsonResult queryGrid(BidsQuery query) throws Exception {
        List<BidsPO> list = bidsDAO.queryList(query);
        int count = bidsDAO.queryCount(query);
        Datagrid<BidsPO> datagrid = new Datagrid<>(list, count);
        return JsonResult.success(datagrid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult save(BidsDTO bidsDTO) throws Exception {
        String techId;
        String busId;
        BidsPO bidsPO = new BidsPO();
        BeanUtils.copyProperties(bidsDTO, bidsPO);
        if (StringUtils.isBlank(bidsDTO.getId())) {
            String id = String.valueOf(serialUtil.nextId());
            bidsPO.setId(id);
            bidsPO.setCreateBy(bidsDTO.getLander());
            techId = String.valueOf(serialUtil.nextId());
            generateSubBids(techId, id, 0, FlowTypeEnum.BID_TECH.getFlowType(), bidsDTO.getLander());
            busId = String.valueOf(serialUtil.nextId());
            generateSubBids(busId, id, 1, FlowTypeEnum.BID_BUS.getFlowType(), bidsDTO.getLander());
            bidsPO.setTechId(techId);
            bidsPO.setBusId(busId);
            bidsDAO.insert(bidsPO);
            // 保存附件
            List<AttachmentPO> attachments = bidsDTO.getAttachments();
            if (attachments != null && attachments.size() > 0) {
                attachmentService.save(attachments, id);
            }
        } else {
            techId = bidsDTO.getTechId();
            busId = bidsDTO.getBusId();
            bidsPO.setModifyBy(bidsDTO.getLander());
            bidsDAO.update(bidsPO);
        }

        // 保存技术标、商务标流程
        flowTaskService.saveTaskFlow(String.valueOf(techId), bidsDTO.getTechFlowList());
        flowTaskService.saveTaskFlow(String.valueOf(busId), bidsDTO.getBusFlowList());
        return JsonResult.success();
    }

    /**
     * 生成技术标和商务标任务
     *
     * @param id           子任务ID
     * @param pId          父任务ID
     * @param category     类型（0：技术标，1：商务标）
     * @param flowTypeCode 流程类型编码
     * @param lander       登陆人
     */
    private void generateSubBids(String id, String pId, int category, String flowTypeCode, String lander) throws SQLException {
        // 技术标
        BidsSubPO subBidsPO = new BidsSubPO();
        subBidsPO.setId(id);
        subBidsPO.setpId(pId);
        subBidsPO.setCategory(category);
        subBidsPO.setFlowTypeCode(flowTypeCode);
        subBidsPO.setCreateBy(lander);
        bidsDAO.insertBidsSub(subBidsPO);
    }

    @Override
    public JsonResult findVoById(String id, String type) throws Exception {
        BidsVO bidsVO;
        if (FlowTypeEnum.BID_TECH.getFlowType().equals(type)) {
            bidsVO = bidsDAO.findMainVoBySubId(id);
        } else if (FlowTypeEnum.BID_BUS.getFlowType().equals(type)) {
            bidsVO = bidsDAO.findMainVoBySubId(id);
        } else {
            bidsVO = bidsDAO.findVoById(id);
        }
        return JsonResult.success(bidsVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult deleteById(String id) throws Exception {
        BidsPO bidsPO = bidsDAO.findPoById(id);
        bidsDAO.deleteById(id);
        bidsDAO.deleteSubByPid(id);
        attachmentService.delete(id);
        flowTaskService.deleteFlowByTaskId(bidsPO.getTechId());
        flowTaskService.deleteFlowByTaskId(bidsPO.getBusId());
        return JsonResult.success();
    }

    @Override
    public JsonResult querySubGrid(BidsQuery query) throws Exception {
        List<BidsSubVO> list = bidsDAO.querySubList(query);
        int count = bidsDAO.querySubCount(query);
        Datagrid<BidsSubVO> datagrid = new Datagrid<>(list, count);
        return JsonResult.success(datagrid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult initiated(String id, String lander) throws Exception {
        BidsPO bidsPO = bidsDAO.findPoById(id);
        if (bidsPO.getState() != 0) {
            return JsonResult.failure("当前状态无法发起");
        }
        // 技术标发起
        FlowTaskParam techParam = new FlowTaskParam();
        techParam.setTaskId(bidsPO.getTechId());
        techParam.setFlowTypeCode(FlowTypeEnum.BID_TECH.getFlowType());
        techParam.setState(0);
        techParam.setOperation("initiated");
        techParam.setAllowRevoke(0);
        techParam.setCreateBy(lander);
        flowTaskService.flowSubmit(techParam);
        // 商务标发起
        FlowTaskParam busParam = new FlowTaskParam();
        busParam.setState(0);
        busParam.setTaskId(bidsPO.getBusId());
        busParam.setFlowTypeCode(FlowTypeEnum.BID_BUS.getFlowType());
        busParam.setOperation("initiated");
        busParam.setAllowRevoke(0);
        busParam.setCreateBy(lander);
        flowTaskService.flowSubmit(busParam);
        // 更新当前状态
        bidsPO.setState(1);
        bidsDAO.update(bidsPO);
        return JsonResult.success();
    }

    @Override
    public List<AttachmentPO> queryAttachments(String sId, String type) throws Exception {
        Integer category = null;
        if (FlowTypeEnum.BID_TECH.getFlowType().equals(type)) {
            category = 1;
        } else if (FlowTypeEnum.BID_BUS.getFlowType().equals(type)) {
            category = 2;
        }
        return attachmentService.queryAttachments(sId, category);
    }

    @Override
    public JsonResult saveFile(AttachmentPO attachmentPO, String type) throws Exception {
        int category = 0;
        if (FlowTypeEnum.BID_TECH.getFlowType().equals(type)) {
            category = 1;
        } else if (FlowTypeEnum.BID_BUS.getFlowType().equals(type)) {
            category = 2;
        }
        attachmentPO.setCategory(category);
        attachmentService.save(attachmentPO, attachmentPO.getsId());
        return null;
    }

    @Override
    public JsonResult deleteFile(String id) throws Exception {
        attachmentService.deleteById(id);
        return JsonResult.success();
    }

    @Override
    public JsonResult saveResult(BidsResultDTO bidsResultDTO, String lander) throws Exception {
        BidsPO bidsPO = new BidsPO();
        BeanUtils.copyProperties(bidsResultDTO, bidsPO);
        bidsPO.setModifyBy(lander);
        bidsDAO.update(bidsPO);
        return JsonResult.success();
    }

    @Override
    public JsonResult confirmResult(BidsResultDTO bidsResultDTO, String lander) throws Exception {
        BidsPO bidsPO = new BidsPO();
        BeanUtils.copyProperties(bidsResultDTO, bidsPO);
        bidsPO.setBidStateConfirmed(true);
        bidsPO.setModifyBy(lander);
        bidsDAO.update(bidsPO);
        // 如果是中标状态，更新项目状态为已中标
        if (bidsResultDTO.getBidState() == 1) {
            ProjectPO projectPO = new ProjectPO();
            projectPO.setId(bidsResultDTO.getProjectId());
            projectPO.setStatus(ProjectStatusEnum.BID_WIN.getCode());
            projectPO.setStatusName(ProjectStatusEnum.BID_WIN.getName());
            projectPO.setModifyBy(lander);
            // 别忘了更新其他项目信息
            projectService.save(projectPO);
        }
        return JsonResult.success();
    }

    @Override
    public void notify(FlowTaskNotifyDTO flowTaskNotifyDTO) throws Exception {
        // 如果审批结果为结束，则判断另外一条是否已通过，通过的话更新主单据为审批通过
        if (flowTaskNotifyDTO.getNextState() == 99) {
            BidsSubPO bidsSubPO = bidsDAO.findSubById(flowTaskNotifyDTO.getTaskId());
            int count = bidsDAO.queryCompleteSubCount(bidsSubPO.getpId());
            if (count == 2) {
                BidsPO bidsPO = new BidsPO();
                bidsPO.setId(bidsSubPO.getpId());
                bidsPO.setState(99);
                bidsDAO.update(bidsPO);
            }
        }
    }
}
